package cn.jbolt.core.poi.excel;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import com.jfinal.kit.StrKit;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * JBolt提供Excel导出封装类
 *
 * @ClassName: JBoltExcel
 * @author: JFinal学院-小木 QQ：909854136
 * @date: 2020年3月10日
 */
public class JBoltExcel {
    public static final int OPT_MODE_IMPORT = 1;// 导入
    public static final int OPT_MODE_EXPORT = 2;// 普通导出
    public static final int OPT_MODE_EXPORT_BY_TPL = 3;// 普通加载模板后导出
    public static final int OPT_MODE_EXPORT_BY_DYNAMIC_TPL = 4;// 加载动态模板后导出

    private int optMode;// 1 导入 2 导出操作类型 3 普通加载模板后导出 4 加载动态模板后导出
    private String fileName;// 文件名
    private boolean big;// 是否大文件导出设置
    private boolean xlsx;// 格式设置
    private File fromFile;// 读取用的文件
    private List<JBoltExcelSheet> sheets;

    private JBoltExcel(int optMode) {
        this.optMode = optMode;
        this.big = false;
        this.xlsx = false;
    }

    private JBoltExcel(int optMode, File file) {
        if (!FileUtil.exist(file)) {
            throw new RuntimeException("File not exist:" + file.getAbsolutePath());
        }
        this.optMode = optMode;
        this.big = false;
        this.fromFile = file;
        processFileIsXlsx(file);
    }

    private void processFileIsXlsx(File file) {
        String suffix = FileNameUtil.getSuffix(file);
        this.xlsx = "xlsx".equalsIgnoreCase(suffix);
    }

    private JBoltExcel(File fromFile) {
        this(OPT_MODE_IMPORT);
        if (!FileUtil.exist(fromFile)) {
            throw new RuntimeException("File not exist:" + fromFile.getAbsolutePath());
        }
        this.fromFile = fromFile;
        processFileIsXlsx(fromFile);
    }

    private JBoltExcel(String fromFilePath) {
        this(new File(fromFilePath));
    }

    /**
     * 创建excel 导出使用
     *
     * @return
     */
    public static JBoltExcel create() {
        return new JBoltExcel(OPT_MODE_EXPORT);
    }

    /**
     * 使用模板 导出使用
     *
     * @param tplPath
     * @return
     */
    public static JBoltExcel useTpl(String tplPath) {
        return createByTpl(tplPath);
    }

    /**
     * 使用模板 导出使用
     *
     * @param tplFile
     * @return
     */
    public static JBoltExcel useTpl(File tplFile) {
        return createByTpl(tplFile);
    }

    /**
     * 从指定模板加载 用于使用模板导出
     *
     * @param tplPath
     * @return
     */
    public static JBoltExcel createByTpl(String tplPath) {
		if (StrKit.isBlank(tplPath)) {
			throw new RuntimeException("tplPath is null");
		}
        if (!tplPath.contains("exceltpl") && !FileUtil.isAbsolutePath(tplPath)) {
            tplPath = FileUtil.getAbsolutePath("exceltpl" + File.separator + tplPath);
        }
        return createByTpl(new File(tplPath));
    }

    /**
     * 从指定模板加载 用于使用模板导出
     *
     * @param tplFile
     * @return
     */
    public static JBoltExcel createByTpl(File tplFile) {
        return new JBoltExcel(OPT_MODE_EXPORT_BY_TPL, tplFile);
    }

    /**
     * 从指定路径读取数据 导入使用
     *
     * @param filePath
     * @return
     */
    public static JBoltExcel from(String filePath) {
        if (StrKit.isBlank(filePath)) {
            throw new RuntimeException("filepath is null");
        }
        return new JBoltExcel(filePath);
    }

    /**
     * 从指定文件读取数据 导入使用
     *
     * @param file
     * @return
     */
    public static JBoltExcel from(File file) {
        return new JBoltExcel(file);
    }

    public boolean isXlsx() {
        return xlsx;
    }

    public JBoltExcel setXlsx(boolean isXlsx) {
        if (this.big) {
            this.xlsx = true;
        } else {
            this.xlsx = isXlsx;
        }
        return this;
    }

    /**
     * 获得文件bytes
     *
     * @return
     */
    public byte[] toByteArray() {
        return JBoltExcelUtil.getExcelBytes(this);
    }

    /**
     * 存到文件
     *
     * @param saveFilePath
     * @return
     */
    public File toFile(String saveFilePath) {
        return JBoltExcelUtil.saveFile(this, saveFilePath);
    }

    public boolean isBig() {
        return big;
    }

    public JBoltExcel setBig(boolean isBig) {
        this.big = isBig;
        if (isBig) {
            this.xlsx = true;
        }
        return this;
    }

    public String getFileName() {
        return fileName;
    }

    public JBoltExcel setFileName(String fileName) {
        this.fileName = fileName;
        return this;
    }

    public File getFromFile() {
        return fromFile;
    }

    public int getOptMode() {
        return optMode;
    }

    public JBoltExcel addSheet(JBoltExcelSheet sheet) {
        if (this.sheets == null) {
            this.sheets = new ArrayList<JBoltExcelSheet>();
        }
        sheet.setExcel(this);
        this.sheets.add(sheet);
        return this;
    }

    public JBoltExcel setSheets(JBoltExcelSheet... sheets) {
        if (sheets != null && sheets.length > 0) {
            for (JBoltExcelSheet sheet : sheets) {
                addSheet(sheet);
            }
        }
        return this;
    }

    /**
     * 依赖sheet的name 获取指定sheet
     *
     * @param name
     * @return
     */
    public JBoltExcelSheet getSheet(String name) {
        if (this.sheets == null || this.sheets.isEmpty()) {
            return null;
        }
        return sheets.stream().filter(sheet -> sheet.getName().equals(name)).findFirst().orElse(null);
    }

    /**
     * 依赖sheetIndex 获取指定sheet
     *
     * @param sheetIndex
     * @return
     */
    public JBoltExcelSheet getSheet(int sheetIndex) {
        if (this.sheets == null || this.sheets.isEmpty()) {
            return null;
        }
        return sheets.stream().filter(sheet -> (sheet.getSheetIndex() == sheetIndex)).findFirst().orElse(null);
    }

    public boolean isExportByTpl() {
        return optMode == OPT_MODE_EXPORT_BY_TPL;
    }

    public boolean isExport() {
        return optMode == OPT_MODE_EXPORT;
    }

    public boolean isImport() {
        return optMode == OPT_MODE_IMPORT;
    }

    public List<JBoltExcelSheet> getSheets() {
        return sheets;
    }

    public int getSheetSize() {
        return sheets == null ? 0 : sheets.size();
    }

    public void setSheets(List<JBoltExcelSheet> sheets) {
        this.sheets = sheets;
    }

}
